<template>
    <div class="drag-verify">
        <div class="range" :class="verifyResult ? 'success' : ''">
            <div class="block" @mousedown="onStart" @touchstart="onStart">
                <el-icon><Right /></el-icon>
            </div>
            <span class="text">
                {{ verifyResult ? successText : startText }}
            </span>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";

const emit = defineEmits(["update"]);
defineProps({
    value: {
        type: Boolean,
        defalut: false,
    },
    // 成功图标
    successIcon: {
        type: String,
        default: "iconfont icon-status-nor",
    },
    // 成功文字
    successText: {
        type: String,
        default: "验证成功",
    },
    // 开始的图标
    startIcon: {
        type: String,
        default: "iconfont icon-login-slid",
    },
    // 开始的文字
    startText: {
        type: String,
        default: "请拖动滑块到最右边完成验证",
    },
});

const verifyResult = ref(false); // 验证结果
const isTouch = "ontouchstart" in document.documentElement;
const moveEvent = isTouch ? "touchmove" : "mousemove";
const upEvent = isTouch ? "touchend" : "mouseup";

// 滑块触摸开始
const onStart = (ev: MouseEvent | TouchEvent) => {
    let disX = 40; // 滑块移动距离
    const iconWidth = 40; // 滑动图标宽度
    const ele = document.querySelector(".drag-verify .block") as HTMLElement;
    const startX =
        (ev as MouseEvent).clientX || (ev as TouchEvent).touches[0].pageX;
    const parentWidth = ele.offsetWidth;
    const MaxX = parentWidth - iconWidth - 6;
    if (verifyResult.value) {
        return false;
    }

    // 滑块触摸移动
    const onMove = (e: MouseEvent | TouchEvent) => {
        const endX =
            (e as MouseEvent).clientX || (e as TouchEvent).touches[0].pageX;
        disX = endX - startX;
        if (disX <= 0) {
            disX = 0;
        }
        if (disX >= MaxX - iconWidth) {
            disX = MaxX;
        }
        ele.style.transition = ".1s all";
        ele.style.transform = `translateX(${disX}px)`;
    };

    // 滑块触摸结束
    const onEnd = () => {
        if (disX !== MaxX) {
            ele.style.transition = ".5s all";
            ele.style.transform = "translateX(0)";
        } else {
            // 执行成功
            verifyResult.value = true;
            emit("update", verifyResult.value);
        }

        document.removeEventListener(moveEvent, onMove);
        document.removeEventListener(upEvent, onEnd);
    };

    document.addEventListener(moveEvent, onMove);
    document.addEventListener(upEvent, onEnd);
};
</script>
<style lang="less" scoped>
.drag-verify {
    width: 100%;
    height: 40px;
    margin: 0 auto;
    .range {
        height: 36px;
        width: 100%;
        background-color: #ececee;
        position: relative;
        border-radius: 5px;
        transition: 1s all;
        user-select: none;
        color: #666;
        overflow: hidden;
        display: flex;
        justify-content: center;
        align-items: center;
        &.success {
            background-color: #ddd;
            color: blue;
            .text {
                position: relative;
                z-index: 1;
            }
            .block i {
                color: #ddd;
            }
        }
        .block {
            display: block;
            position: absolute;
            left: calc(-100% + 44px);
            width: 100%;
            height: 85%;
            margin-top: -2px;
            background: #ddd;
            border-radius: 4px;
            overflow: hidden;
            i {
                position: absolute;
                right: 0;
                width: 40px;
                height: 100%;
                font-size: 20px;
                color: #ddd;
                background-color: #fff;
                border: 1px solid #e5e5e5;
                border-radius: 4px;
                cursor: pointer;
                display: flex;
                justify-content: center;
                align-items: center;
            }
        }
    }
}
</style>
